/**
 * \file
 * \brief Represents a list of Label structures.
 * 
 * The structure is used to store the data of the compiling package
 * Symbol table is built from 2 sources:
 *  -# the precompiled pieces of the symbol table;
 *  -# the package in the compiling phase;
 *
 * The building package data is stored in a set of structure which uses actual
 * pointers.
 * 
 * This particular structure is used to store the various Labels in the package.
 *
 * \date Nov 25, 2013
 * \author koldar
 */

#ifndef LABELLIST_H_
#define LABELLIST_H_

#include "Label.h"

/**The base element of the list. The list built is a singly-linked typed
 * list.
 *
 */
typedef struct LabelListElement {
	//the label stored in the list
	Plabel label;
	//the next label stored in the list
	struct LabelListElement* next;
} LabelListElement;

/**A pointer to an element of the list. The pointer
 * of the first element of the list is equal to the
 * pointer of the list.
 *
 */
typedef LabelListElement* PlabelListElement;

/**A pointer to the beginning of the list
 *
 */
typedef LabelListElement* LabelList;

/**A pointer to the pointer of the first element of the list.
 * This typedef is useful to pass the list in a function
 *
 */
typedef LabelList* PlabelList;


/**@brief creates a new list storing a set of labels to be used in utlist.h
 *
 * For further information see the page http://troydhanson.github.io/uthash/utlist.html
 *
 * \post
 * 	\li a new pointer is correcly initialized to be used with utlist.h.
 *
 *
 */
PlabelList initLabelList();

/**@brief free a list entirely.
 *
 * The various Labels structures pointed by the list *will not* be freed
 *
 * \post
 *  \li the list is deallocates and its pointer is set to NULL
 *
 *  @param list the list to be freed
 */
void freeLabelList(PlabelList list);

/**@brief prints a string representation af the list
 *
 * \pre
 *  \li f file open in write mode;
 *  \li list not NULL;
 * \post
 *  \li f changed forever
 *
 *  @param f the file to write the data on
 *  @param list the list to be printed out
 */
void printLabelList(FILE* f, PlabelList list);

/**@brief adds a label inside the list
 *
 * \pre
 *	\li label not NULL;
 *	\li list initialized correctly with initLabelList();
 * \post
 *  \li at the end of the list the passed label is added;
 *  \li a new LabelListElement is created. It must be free *manually*, for example with:
 *  	- removeLabel();
 *  	- freeLabelList();
 *
 *  @param label the label to be added
 *  @param list that will hold the given label
 */
void addLabelToLabelList(Plabel label,PlabelList list);

/**@brief find wether or not the list ocntains the specific label
 *
 * \pre
 * 	\li label not NULL;
 * 	\li list initialized correctly with initLabelList();
 *
 * @param label the label to find
 * @param list the list in which look the label for
 * @return the pointer to the label if the label is contained in the list, NULL otherwise
 */
Plabel findLabelInLabelList(Plabel label, PlabelList list);

/**@brief remove a given label, if exists
 *
 * Removes the first occurence of the label in the list.
 * Wether the list does not contain the label, nothing will change
 * in the given list.
 *
 * \pre
 *  \li label not NULL;
 *  \li list initialized correctly with initLabelList();
 * \post
 *  \li the first occurence of label is removed from the list, if present.
 *
 *  @param label the label to be removed;
 *  @param list the list to be handled;
 *
 */
void removeLabelFromLabelList(Plabel label, PlabelList list);

/**@brief return the number of elements in the list
 *
 * \pre
 *  \li list initialized through initLabelList();
 *
 * @param list the list to analyze
 *
 * @return the length of the given list
 *
 */
int getLabelListSize(PlabelList list);

#endif /* LABELLIST_H_ */
